package com.aplink.generic.xmlparser;

import android.content.Context;

import com.aplink.generic.constant.ConfigParameter;
import com.aplink.generic.pojo.xml.GeoMapConfig;
import com.aplink.generic.pojo.xml.GeoPointStatus;

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import java.io.IOException;
import java.util.ArrayList;

import javax.xml.parsers.ParserConfigurationException;

public class GeoFormatParser {

    public static GeoMapConfig parse( Document doc, String tagname ) {

        final GeoMapConfig geoMapConfig = new GeoMapConfig();

        final NodeList nList = doc.getElementsByTagName( tagname );

        if ( nList.getLength() == 0 ) {
            return null;
        }
        final Node nNode = nList.item( 0 );

        if ( nNode.getNodeType() == Node.ELEMENT_NODE ) {

            final Element element = (Element) nNode;

            // process for Map_coordinate
            NodeList nodes = element
                    .getElementsByTagName( ConfigParameter.MAP_COORDINATE );
            if ( nodes.getLength() == 0 ) {
                return null;
            }

            final Node nCoordinateNode = nodes.item( 0 );

            if ( nCoordinateNode.getNodeType() == Node.ELEMENT_NODE ) {
                final Element elementControlNode = (Element) nCoordinateNode;

                // set idLatitude in database
                final NodeList nodeLatitude = elementControlNode
                        .getElementsByTagName( ConfigParameter.MAP_COORDINATE_LATITUDE );
                if ( nodeLatitude.getLength() != 0 ) {
                    final Node nDetailNode = nodeLatitude.item( 0 );
                    if ( nDetailNode.hasAttributes() ) {
                        // find idLatitude
                        final Attr attrDetail = (Attr) nDetailNode
                                .getAttributes()
                                .getNamedItem(
                                        ConfigParameter.MAP_COORDINATE_LATITUDE_ID );
                        if ( attrDetail != null ) {
                            final String idLatitude = attrDetail.getNodeValue();
                            geoMapConfig.setLatitudeId( idLatitude );
                        }
                    }
                }

                // set idLongitude in database
                final NodeList nodeLongitude = elementControlNode
                        .getElementsByTagName( ConfigParameter.MAP_COORDINATE_LONGITUDE );
                if ( nodeLongitude.getLength() != 0 ) {
                    final Node nDetailNode = nodeLongitude.item( 0 );
                    if ( nDetailNode.hasAttributes() ) {
                        // find idLongitude
                        final Attr attrDetail = (Attr) nDetailNode
                                .getAttributes()
                                .getNamedItem(
                                        ConfigParameter.MAP_COORDINATE_LONGITUDE_ID );
                        if ( attrDetail != null ) {
                            final String idLongitude = attrDetail.getNodeValue();
                            geoMapConfig.setLongitudeId( idLongitude );
                        }
                    }
                }
            }

            // process for Map_address
            nodes = element.getElementsByTagName( ConfigParameter.MAP_ADDRESS );
            if ( nodes.getLength() != 0 ) {
                final Node nAddressNode = nodes.item( 0 );
                if ( nAddressNode.hasAttributes() ) {

                    // find attr address isDisplay
                    Attr attr = (Attr) nAddressNode
                            .getAttributes()
                            .getNamedItem( ConfigParameter.MAP_ADDRESS_ISDISPLAY );
                    if ( attr != null ) {
                        final String addressIsDisplay = attr.getNodeValue();
                        if ( addressIsDisplay.compareToIgnoreCase( "Y" ) == 0 ) {
                            geoMapConfig.setIsDisplayAddress( true );
                        }

                    }

                    // find attr address id
                    attr = (Attr) nAddressNode.getAttributes().getNamedItem(
                            ConfigParameter.MAP_ADDRESS_ID );
                    if ( attr != null ) {
                        final String addressId = attr.getNodeValue();
                        geoMapConfig.setAddressId( addressId );
                    }
                }
            }

            // process for Map_PointStatus
            nodes = element
                    .getElementsByTagName( ConfigParameter.MAP_POINT_STATUS );
            if ( nodes.getLength() == 0 ) {
                return null;
            }

            final Node nPointStatusNode = nodes.item( 0 );
            if ( nPointStatusNode.hasAttributes() ) {
                // find attr StatusId
                final Attr attr = (Attr) nPointStatusNode.getAttributes()
                        .getNamedItem( ConfigParameter.MAP_POINT_STATUS_ID );
                if ( attr != null ) {
                    final String statusId = attr.getNodeValue();
                    geoMapConfig.setStatusId( statusId );
                }
            }

            if ( nPointStatusNode.getNodeType() == Node.ELEMENT_NODE ) {

                final ArrayList<GeoPointStatus> arrGeoPoints = new ArrayList<GeoPointStatus>();
                final Element PointStatusElement = (Element) nPointStatusNode;

                // process for Markers
                final NodeList markerNodes = PointStatusElement
                        .getElementsByTagName( ConfigParameter.MAP_POINT_STATUS_MARKER );
                if ( markerNodes.getLength() == 0 ) {
                    return null;
                }

                for ( int i = 0 ; i < markerNodes.getLength() ; i++ ) {
                    final Node nDetailNode = markerNodes.item( i );
                    final GeoPointStatus geoPointStatus = new GeoPointStatus();
                    if ( nDetailNode.hasAttributes() ) {

                        // find status
                        Attr attrDetail = (Attr) nDetailNode
                                .getAttributes()
                                .getNamedItem(
                                        ConfigParameter.MAP_POINT_STATUS_MARKER_STATUS );
                        if ( attrDetail != null ) {
                            final String status = attrDetail.getNodeValue();
                            geoPointStatus.setmStatus( status );
                        }
                        // find snippet
                        attrDetail = (Attr) nDetailNode
                                .getAttributes()
                                .getNamedItem(
                                        ConfigParameter.MAP_POINT_STATUS_MARKER_SNIPPET );
                        if ( attrDetail != null ) {
                            final String snippet = attrDetail.getNodeValue();
                            geoPointStatus.setmSnippet( snippet );
                        }
                        // find icon
                        attrDetail = (Attr) nDetailNode
                                .getAttributes()
                                .getNamedItem(
                                        ConfigParameter.MAP_POINT_STATUS_MARKER_ICON );
                        if ( attrDetail != null ) {
                            final String icon = attrDetail.getNodeValue();
                            geoPointStatus.setmIcon( icon );
                        }

                    }

                    // we add this geoPointStatus into arrGeoPoints
                    if ( ! geoPointStatus.getmStatus().equals( "" ) ) {
                        arrGeoPoints.add( geoPointStatus );
                    }
                }

                if ( arrGeoPoints.size() > 0 ) {
                    geoMapConfig.setmArrPointStatus( arrGeoPoints );
                }
            }
        }

        return geoMapConfig;
    }

    public static GeoMapConfig parserGeoMapConfig( Context paramContext,
                                                   int xmlFileId, String tagName ) {
        try {
            final Document document = XMLPaserUtil.openDocumentFrom( paramContext,
                    xmlFileId );
            return parse( document, tagName );
        } catch ( final ParserConfigurationException e ) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch ( final SAXException e ) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch ( final IOException e ) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    public static GeoMapConfig parserGeoMapConfig( Context paramContext,
                                                   String xmlfilename, String tagname ) {
        try {
            final Document document = XMLPaserUtil.openDocumentFrom( paramContext,
                    xmlfilename );
            return parse( document, tagname );
        } catch ( final ParserConfigurationException e ) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch ( final SAXException e ) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch ( final IOException e ) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
}
